package com.appleyk.nio;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Scanner;

/**
 * <p></p>
 *
 * @author appleyk
 * @version V.0.1.1
 * @blob https://blog.csdn.net/appleyk
 * @github https://github.com/kobeyk
 * @date created on 8:58 2021/2/2
 */
public class NIOChatClient {

    private static Logger logger = LoggerFactory.getLogger(NIOChatClient.class);

    private Selector selector;
    private final String host = "localhost";
    private final int port = 6666;
    private SocketChannel socketChannel;
    private String clientName;

    public NIOChatClient() {
        try{
            selector = Selector.open();
            socketChannel = SocketChannel.open(new InetSocketAddress(host,port));
            socketChannel.configureBlocking(false);
            socketChannel.register(selector, SelectionKey.OP_READ);
            clientName = socketChannel.getLocalAddress().toString().substring(1);
        }catch (IOException e){
            logger.error(e.getMessage());
        }
    }

    public void recvInfo(){
        while (true){
            try{
                int select = selector.select();
                if(select == 0){
                    continue;
                }
                Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();
                while (keyIterator.hasNext()){
                    SelectionKey key = keyIterator.next();
                    // 客户端只有读事件
                    if (key.isReadable()){
                        SocketChannel channel = (SocketChannel)key.channel();
                        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                        channel.read(byteBuffer);
                        logger.info("from 客户端 {}",new String(byteBuffer.array()));
                    }
                    // 防止发生事件的通道被重复处理
                    keyIterator.remove();
                }
            }catch (IOException e){
                logger.error(e.getMessage());
            }
        }
    }

    public void sendInfo(String info) throws IOException{
        info = clientName + "说 :" + info;
        ByteBuffer byteBuffer = ByteBuffer.wrap(info.getBytes());
        socketChannel.write(byteBuffer);
    }

    public static void main(String[] args) throws IOException{
        NIOChatClient chatClient = new NIOChatClient();
        new Thread(()->{
            try{
                // 群聊不需要实时性太高，2s轮序一次消息就行
                Thread.sleep(2000);
                chatClient.recvInfo();
            }catch (InterruptedException e){
                logger.error(e.getMessage());
            }
        }).start();

        // 主线程来写
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()){
            String info = scanner.next();
            chatClient.sendInfo(info);
            logger.info("我说 ："+info);
        }
    }
}
